package com.tanhua.server.service;

import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.cloud.commons.lang.StringUtils;
import com.github.tobato.fastdfs.domain.conn.FdfsWebServer;
import com.github.tobato.fastdfs.domain.fdfs.StorePath;
import com.github.tobato.fastdfs.service.FastFileStorageClient;
import com.tanhua.commons.SoulConstants;
import com.tanhua.commons.exception.TanHuaException;
import com.tanhua.dubbo.api.db.UserInfoApi;
import com.tanhua.dubbo.api.mongo.FriendApi;
import com.tanhua.dubbo.api.mongo.SoundApi;
import com.tanhua.dubbo.api.mongo.UserLikeApi;
import com.tanhua.model.db.UserInfo;
import com.tanhua.model.mongo.Friend;
import com.tanhua.model.mongo.Sound;
import com.tanhua.model.mongo.UserLike;
import com.tanhua.model.vo.SoundVO;
import com.tanhua.server.interceptor.UserHolder;
import org.apache.commons.collections.ListUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.bson.types.ObjectId;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

@Service
public class PeachBlossomService {

    @Autowired
    private StringRedisTemplate redisTemplate;

    @Autowired
    private FastFileStorageClient client;

    @Autowired
    private FdfsWebServer fdfsWebServer;

    @DubboReference
    private SoundApi soundApi;

    @DubboReference
    private UserLikeApi userLikeApi;

    @DubboReference
    private FriendApi friendApi;

    @DubboReference
    private UserInfoApi userInfoApi;


    /**
     * 探花传音  获取音频
     * @return
     */
    public SoundVO getPeachBlossom() {
        //本机用户信息
        Long userId = UserHolder.getUserId();
        UserInfo userInfo = userInfoApi.getById(userId);
        //本机用户性别
        String gender = userInfo.getGender();
        //获取传音次数
        String getSoundKey = "GET_SOUND_TIMES_" + userId;
        String sTimes = redisTemplate.opsForValue().get(getSoundKey);
        //查找已经推荐过的音频id
        String alreadyGetSoundKey = "ALREADY_GET_SOUND_" + userId;
        Set<String> alreadyGetId = redisTemplate.opsForSet().members(alreadyGetSoundKey);
        //查找本机用户的好友Id
        List<Friend> friendList = friendApi.getAllFriend(userId);
        List<Long> friendIds = friendList.stream().map(Friend::getFriendId).collect(Collectors.toList());
        //查找本机用户不喜欢的Id
        List<UserLike> userLikes = userLikeApi.exist(userId);
        List<Long> dislikeIds = userLikes.stream().map(UserLike::getLikeUserId).collect(Collectors.toList());
        //查找redis中今日以及听过的用户id
        String alreadyGetUserKey = "ALREADY_GET_USERID_" + userId;
        Set<String> alreadyGetUserId = redisTemplate.opsForSet().members(alreadyGetUserKey);
        List<Long> alreadyGetUserIdList = alreadyGetUserId.stream().map(Long::valueOf).collect(Collectors.toList());


        //合并需要排除的用户Id
        List<Long> excludeIds = CollectionUtil.unionAll(dislikeIds, friendIds, alreadyGetUserIdList);
        //剩余次数
        Integer time ;
        if (sTimes == null) {
            //如果redis中没有用户操作获取音频的次数
            //说明用户这是第一次获取音频则设置剩余次数为2
            time = 3;
        }else if (Integer.valueOf(sTimes) > 1 ) {
            //如果有且剩余次数大于0则设置剩余次数减1
            time = Integer.valueOf(sTimes) - 1;
        }else{
            //如果剩余次数为0则抛出异常
            Sound sound = new Sound();
            return SoundVO.init(userInfo, sound, time = 0);
        }
        //获取音频对象
        Sound sound = soundApi.getOne(gender, alreadyGetId, excludeIds);
        if (sound.getSoundUrl()==null){
            //如果音频没有路径抛出异常
            throw new TanHuaException("暂无推荐,请稍后再试");
        }
        //根据音频对象查音频所属用户信息
        UserInfo info = userInfoApi.getById(sound.getUserId());
        //redis保存获取过的用户id
        redisTemplate.opsForSet().add(alreadyGetUserKey, info.getId().toString());
        //保存获取次数到redis
        redisTemplate.opsForValue().set(getSoundKey, time.toString());
        //存放音频id到已获得音频redis中
        redisTemplate.opsForSet().add(alreadyGetSoundKey,sound.getId().toString());
        //创建SoundVo对象并返回
        return SoundVO.init(info, sound, time);
    }

    /**
     * 发送语音
     * @param soundFile
     */
    public void sendSound(MultipartFile soundFile) {

        Long userId = UserHolder.getUserId();
        String key = SoulConstants.SEND_SOUND_TIME + userId;
        String timeStr = redisTemplate.opsForValue().get(key);
        int time = 0;
        if(StringUtils.isNotEmpty(timeStr)) {
            time = Integer.parseInt(timeStr);
            if (time == 3) {
                throw new TanHuaException("今日发送语音次数已用完");
            }
        }

        String filename = soundFile.getOriginalFilename();
        String extension = filename.substring(filename.lastIndexOf(".")+1);
        try {
            StorePath path = client.uploadFile(soundFile.getInputStream(), soundFile.getSize(), extension, null);
            String soundUrl = fdfsWebServer.getWebServerUrl() + path.getFullPath();

            UserInfo userInfo = userInfoApi.getById(userId);
            Sound sound = new Sound();
            sound.setUserId(userInfo.getId());
            sound.setGender(userInfo.getGender());
            sound.setSoundUrl(soundUrl);
            soundApi.save(sound);
            //使用次数写入redis
            redisTemplate.opsForValue().set(key, time + 1 + "");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
